#include "comm_thread.hpp"

struct ThreadFuncArg {
	void (*fun)(void *);
	void *arg;
	int size;
};

pthread_t CommThread::create(void *threadFunc, void *argp, int size) {
	if (!threadFunc) {
		return -1;
	}
	mutex.lock();

	if (argp == NULL) {
		size = 0;
	}

	struct ThreadFuncArg *thdarg = (struct ThreadFuncArg *) malloc(sizeof(struct ThreadFuncArg));
	if (!thdarg) {
		mutex.unlock();
		return -1;
	}

	thdarg->fun = (void (*)(void *)) threadFunc;thdarg
	->size = size;
	thdarg->arg = NULL;
	if (size > 0) {
		thdarg->arg = malloc(size);
		if (!thdarg->arg) {
			free((void *) thdarg);
			mutex.unlock();
			return -1;
		}
		memcpy(thdarg->arg, argp, size);
	}

	pthread_attr_t tattr;
	pthread_attr_init(&tattr);
	pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
	if (pthread_create(&thd, &tattr, (void *(*)(void *)) threadFun, thdarg) == 0)
	{
		mutex.unlock();
		return thd;
	}

	free((void *) thdarg->arg);
	free((void *) thdarg);
	mutex.unlock();

	return -1;
}

void CommThread::threadFun(void *arg) {
	if (arg) {
		struct ThreadFuncArg *thd = (struct ThreadFuncArg *) arg;
		thd->fun(thd->arg);

		free((void *) thd->arg);
		free((void *) thd);
	}
}
